package com.hht.toolanduilibs.util

import android.annotation.SuppressLint
import android.app.WallpaperManager
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.renderscript.Allocation
import android.renderscript.Element
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
import android.util.DisplayMetrics
import android.view.WindowManager
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream


/**
 * Author:chen'hu
 * Time:2023/8/23 15:54
 * Description:This is BitmapUtils
 */
class BitmapUtils(var mContext: Context) {

    companion object {
        fun newInstance(context: Context): BitmapUtils {
            return BitmapUtils(context)
        }
    }

    fun getCompressBlurBitmap(
        bitmap: Bitmap,
        width: Int = 0,
        height: Int = 0,
        radius: Float = 12F,
    ): Bitmap {
        val matrix = Matrix()
        matrix.setScale(0.5f, 0.5f)
        var mBitmap = Bitmap.createBitmap(bitmap,
            (getScreenWidth() - width) / 2,
            (getScreenHeight() - height) / 2,
            width,
            height, matrix, true)
        //压缩下，太大会出问题
        mBitmap = getCompressBitmap(mBitmap, 80);
        return blurBitmap(mBitmap, radius)
    }


    /**
     * 压缩图片质量
     */
    private fun getCompressBitmap(bitmap: Bitmap, quality: Int): Bitmap {
        val byteArrayInputStream = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayInputStream)
        val byte = byteArrayInputStream.toByteArray()
        val ins = ByteArrayInputStream(byte)
        val bm = BitmapFactory.decodeStream(ins)
        ins.close()
        byteArrayInputStream.close()
        return bm
    }

    @SuppressLint("MissingPermission")
    fun getWallpaperDrawable(): Drawable {
        return WallpaperManager.getInstance(mContext).drawable
    }

    @SuppressLint("MissingPermission")
    fun getWallpaperBitmap(): Bitmap {
        val wallpaperDrawable = WallpaperManager.getInstance(mContext).drawable
        // 将Drawable,转成Bitmap
        var bitmap = (wallpaperDrawable as BitmapDrawable).bitmap
        if (bitmap == null) {
            bitmap =
                BitmapFactory.decodeResource(mContext.resources, android.R.mipmap.sym_def_app_icon)
        }
        return bitmap
    }

    @SuppressLint("MissingPermission")
    fun getBlurBitmap(radius: Float = 10F, scaleX: Float = 0.5F, scaleY: Float = 0.5F): Bitmap {
        // 获取壁纸管理器
        val wallpaperDrawable = WallpaperManager.getInstance(mContext).drawable
        // 将Drawable,转成Bitmap
        var mBitmap = (wallpaperDrawable as BitmapDrawable).bitmap
        if (mBitmap == null) {
            mBitmap =
                BitmapFactory.decodeResource(mContext.resources, android.R.mipmap.sym_def_app_icon)
        }
        val matrix = Matrix()
        matrix.setScale(scaleX, scaleY)
        mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.width,
            mBitmap.height, matrix, true)
        return blurBitmap(mBitmap, radius)
    }

    fun getBlurBitmap(
        bitmap: Bitmap,
        radius: Float = 10F,
        scaleX: Float = 0.5F,
        scaleY: Float = 0.5F,
    ): Bitmap {
        var mBitmap: Bitmap
        val matrix = Matrix()
        matrix.setScale(scaleX, scaleY)
        mBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width,
            bitmap.height, matrix, true)
        return blurBitmap(mBitmap, radius)
    }

    /**
     * 模糊图片的具体方法
     * @param blurRadius 模糊数值
     * @param bitmap   需要模糊的图片
     * @return 模糊处理后的图片
     */
    private fun blurBitmap(bitmap: Bitmap, blurRadius: Float): Bitmap {

        // 将缩小后的图片做为预渲染的图片
        val inputBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.width, bitmap.height, false)
        // 创建一张渲染后的输出图片
        val outputBitmap = Bitmap.createBitmap(inputBitmap)

        // 创建RenderScript内核对象
        val rs = RenderScript.create(mContext)
        // 创建一个模糊效果的RenderScript的工具对象
        val blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs))

        // 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间
        // 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去
        val tmpIn = Allocation.createFromBitmap(rs, inputBitmap)
        val tmpOut = Allocation.createFromBitmap(rs, outputBitmap)

        // 设置渲染的模糊程度, 25f是最大模糊度
        blurScript.setRadius(blurRadius)
        // 设置blurScript对象的输入内存
        blurScript.setInput(tmpIn)
        // 将输出数据保存到输出内存中
        blurScript.forEach(tmpOut)
        // 将数据填充到Allocation中
        tmpOut.copyTo(outputBitmap)
        rs.destroy()
        return outputBitmap
    }

    /**
     * 获取屏幕宽度
     */
    private fun getScreenWidth(): Int {
        val wm = mContext
            .getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val outMetrics = DisplayMetrics()
        wm.defaultDisplay.getMetrics(outMetrics)
        return outMetrics.widthPixels
    }

    /**
     * 获取屏幕高度
     */
    private fun getScreenHeight(): Int {
        val wm = mContext
            .getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val outMetrics = DisplayMetrics()
        wm.defaultDisplay.getMetrics(outMetrics)
        return outMetrics.heightPixels
    }
}